/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!		\file		ExplMdl.cc
		\date		june 2010
		\author		TNick

		\brief		Implementation of explorer related classes


	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	Please read ReadMe.txt and Licence.txt in root folder
	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

#include	<assert.h>
#include	"ExplMdl.h"
#include	<QIcon>
#include	<QtDebug>

//QDebug operator<<(QDebug dbg, const Coordinate &c)
// {
//     dbg.nospace() << "(" << c.x() << ", " << c.y() << ")";
//
//     return dbg.space();
// }

/*  INCLUDES    ============================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

/* ------------------------------------------------------------------------- */
					ExplItem::ExplItem		(ExplModel * mdl, ExplNode * parent,
						QString * name, QIcon * icon) : CC_L2D()
{
	/* save provided data */
	pTxt = name;
	pIcon = icon;

	/* no flags set now */
	flg = FNONE;

	/* insert in the chain of father */
	if (parent == NULL)
	{ /* this is a top level item */
		parentModel = mdl;
		mdl->append(this);
		ModelIsParent(true);
	}
	else
	{ /* this is NOT a top level item */
		parentItem = parent;
		parent->append(this);
		ModelIsParent(false);
	}

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
					ExplItem::~ExplItem		()
{
	if (!isTextShared())
	{
		delete pTxt;
	}
	if (!isIconShared())
	{
		delete pIcon;
	}
	//qDeleteAll(columns);

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
int					ExplItem::row		(void)
{
	if (isModelTheFather())
	{ /* this is a top level item */
		return index(&parentModel->hd);
	}
	else
	{ /* this is NOT a top level item */
		return index(&parentItem->hd);
	}
}
/* ========================================================================= */


/*  CLASS    =============================================================== */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */


/*  CLASS    =============================================================== */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

/* ------------------------------------------------------------------------- */
int					ExplModel::columnCount		(const QModelIndex &midx) const
{
	qDebug() << "ExplModel " << this << " asks for column count";
	if (midx.isValid())
	{ /* the request is made for a valid item (not for top level item or leaf) */

		/* so get the pointer to item */
		ExplItem*	pIt = static_cast<ExplItem*>(midx.internalPointer());
		qDebug() << "  valid item requested: " << pIt;

		/* be shure we have a valid item */
		if (pIt == NULL) 
			return 0;

		qDebug() << "  it has " << pIt->columnCount() << " columns";

		/* and ask it about this */
		return pIt->columnCount();
	}
	else
	{/* ? */
		qDebug() << "  invalid item requested: ";
		return 2;
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
QVariant			ExplModel::data				(const QModelIndex &midx,
												 int role) const
{

	qDebug() << "ExplModel " << this << " asks for data on role" << role;

	/* check the validity of provided midx */
	if (midx.isValid())
	{ /* a valid index */

		ExplItem*	pIt = static_cast<ExplItem*>(midx.internalPointer());
		qDebug() << "  a valid index hosting item " << pIt ;
	
		/* be shure we have a valid item */
		if (pIt == NULL) 
			return QVariant();
		qDebug() << "  we have a valid item: " << pIt << " at row " << pIt->row() << " and column " << pIt->columnCount();

		
		int i = midx.column();
		if (i == 0)
		{ /* first column has base data */
			if (role == Qt::DecorationRole)
			{
				return pIt->mainIcon();
			}
			else if (role == Qt::DisplayRole)
			{
				return pIt->mainLabel();
			}
			return QVariant();
		}
		else if (role == Qt::DecorationRole)
		{ /* other columns have data stored inside columns list */
			return (pIt->data(i-1));
		}

		/* other roles are not handled */
		return QVariant();
	}
	else
	{
		qDebug() << "  an invalid index";
		return QVariant();
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
Qt::ItemFlags		ExplModel::flags			(const QModelIndex &midx) const
{
	if (!midx.isValid())
		return 0;

	/* todo: shall allow editing of elements */
	return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
QModelIndex			ExplModel::index			(int a_row, int a_column,
										 const QModelIndex &parent) const
{

	qDebug() << "ExplModel " << this << " req index at row " << a_row << " and column " << a_column;

	//if (!hasIndex(a_row, a_column, parent))
	//{
	//	qDebug() << "  but has no index";
	//	return QModelIndex();
	//}

	ExplNode *		parentItem;
	ExplItem *		theItem;

	/* diferentiate between root and leaf items */
	if (parent.isValid())
	{	/* this is a leaf */

		parentItem = static_cast<ExplNode*>(parent.internalPointer());
		theItem = static_cast<ExplItem*>(parentItem->child(a_row));
		qDebug() << "  an valid parent " << parentItem << " => leaf: " << theItem;
		if (theItem == NULL)
			return QModelIndex();
		return createIndex(a_row, a_column, theItem);
	}
	else
	{	/* this is a root item */

		ExplModel* pEM = (ExplModel*)this;
		theItem = (ExplItem*)pEM->hd.item(a_row);
		qDebug() << "  an invalid parent => top level item " << theItem;
		if (theItem == NULL)
			return QModelIndex();
		return createIndex(a_row, a_column, theItem);
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
QModelIndex			ExplModel::parent			(const QModelIndex &midx) const
{
	qDebug() << "ExplModel " << this << " req parent";

	/* if invalid, discard */
	if (!midx.isValid())
	{
		qDebug() << "  invalid";
		return QModelIndex();
	}


	/* get associated item */
	ExplItem *theItem = static_cast<ExplItem*>(midx.internalPointer());
	if (theItem == NULL)
	{
		qDebug() << "  no associated item";
		return QModelIndex();
	}
	qDebug() << "  associated item is " << theItem;


	/* top level items have no father */
	if (theItem->isModelTheFather())
	{
		qDebug() << "  top level => no parent";
		return QModelIndex();
	}
	else
	{ /* but leafs have */
		ExplItem *parentItem = theItem->parent();
		qDebug() << "  not top level => parent is " << parentItem;
		if (parentItem == NULL)
		{
			/* this case should have been filtered out */
			Q_ASSERT(0);
			return QModelIndex();
		}
		return createIndex(parentItem->row(),0,parentItem);
	}
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
int					ExplModel::rowCount			(const QModelIndex &midx) const
{
	qDebug() << "ExplModel " << this << " req rowCount";

	/* for invalid input */
	if (!midx.isValid())
	{ /* return the number of top level items */
		ExplModel * pDamnConst = (ExplModel*)this;
		qDebug() << "  request for top level returns " << pDamnConst->hd.count() << " items";
		return pDamnConst->hd.count();
	}


	ExplNode *theItem = static_cast<ExplNode*>(midx.internalPointer());
	qDebug() << "  request for leaf returns " << theItem->childCount() << " items";
	return theItem->childCount();
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */

/* ========================================================================= */

/*  CLASS    =============================================================== */
//
//
//
//
/* ------------------------------------------------------------------------- */
/* ========================================================================= */






////! [0]
//ExplModel::ExplModel(QObject *parent)
//    : QAbstractItemModel(parent)
//{
//    QList<QVariant> rootData;
//    rootData << "Title" << "Summary";
//    //rootItem = new ExplItem(rootData);
//    //setup_modelData(data.split(QString("\n")), rootItem);
//	rootItem = new ExplItem();
//	rootItem->setData(0,tr("1"));
//	rootItem->setData(1,tr("2"));
//	rootItem->setData(2,tr("3"));
//	rootItem->setData(3,tr("4"));
//}
//! [0]

//! [1]
//ExplModel::~ExplModel()
//{
//    delete rootItem;
//}
//! [1]


////! [3]
//QVariant ExplModel::data(const QModelIndex &index, int role) const
//{
//	int		i;
//    if (!index.isValid())
//        return QVariant();
//
//    //if (role != Qt::DisplayRole)
//    //    return QVariant();
//
//	i = index.column();
//    ExplItem *item = static_cast<ExplItem*>(index.internalPointer());
//	if (i == 0)
//	{
//		if (role == Qt::DecorationRole)
//		{
//			return item->data(0);
//		}
//		else if (role == Qt::DisplayRole)
//		{
//			return item->data(1);
//		}
//	}
//	else
//	{
//		if (role == Qt::DecorationRole)
//		{
//			return item->data(i+1);
//		}
//	}
//
//
//    return QVariant();
//}
////! [3]

//! [4]
//! [4]

//! [5]
//QVariant ExplModel::headerData(int section, Qt::Orientation orientation,
//                               int role) const
//{
//    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
//        return rootItem->data(section);
//
//    return QVariant();
//}
//! [5]

//! [6]
//! [6]

//! [7]
//! [7]

//! [8]
//int ExplModel::rowCount(const QModelIndex &parent) const
//{
//    ExplItem *parentItem;
//    if (parent.column() > 0)
//        return 0;
//
//    if (!parent.isValid())
//        parentItem = rootItem;
//    else
//        parentItem = static_cast<ExplItem*>(parent.internalPointer());
//
//    return parentItem->childCount();
//}
//! [8]

//void ExplModel::setup_modelData(const QStringList &lines, ExplItem *parent)
//{
	//QList<ExplItem*> parents;
	//QList<int> indentations;
	//parents << parent;
	//indentations << 0;

	//int number = 0;

	//while (number < lines.count()) {
	//    int position = 0;
	//    while (position < lines[number].length()) {
	//        if (lines[number].mid(position, 1) != " ")
	//            break;
	//        position++;
	//    }

	//    QString lineData = lines[number].mid(position).trimmed();

	//    if (!lineData.isEmpty()) {
	//        // Read the column data from the rest of the line.
	//        QStringList columnStrings = lineData.split("\t", QString::SkipEmptyParts);
	//        QList<QVariant> columnData;
	//        for (int column = 0; column < columnStrings.count(); ++column)
	//            columnData << columnStrings[column];

	//        if (position > indentations.last()) {
	//            // The last child of the current parent is now the new parent
	//            // unless the current parent has no children.

	//            if (parents.last()->childCount() > 0) {
	//                parents << parents.last()->child(parents.last()->childCount()-1);
	//                indentations << position;
	//            }
	//        } else {
	//            while (position < indentations.last() && parents.count() > 0) {
	//                parents.pop_back();
	//                indentations.pop_back();
	//            }
	//        }

	//        // Append a new item to the current parent's list of children.
	//        parents.last()->appendChild(new ExplItem(columnData, parents.last()));
	//    }

	//    number++;
	//}
//}


//! [0]
//ExplItem::ExplItem(ExplItem *parent)
//{
//
//    parentItem = parent;
//}
////! [0]
//
////! [1]
//ExplItem::~ExplItem()
//{
//    qDeleteAll(childItems);
//}
//! [1]

//! [2]
//void ExplItem::appendChild(ExplItem *item)
//{
//    childItems.append(item);
//}
//! [2]

//! [3]
//ExplItem *ExplItem::child(int row)
//{
//    return childItems.value(row);
//}
//! [3]

//! [4]
//int ExplItem::childCount() const
//{
//    return childItems.count();
//}
//! [4]

//! [5]
//int ExplItem::columnCount() const
//{
//    return itemData.count() + 1;
//}
//! [5]

//! [6]
//QVariant ExplItem::data(int column) const
//{
//	if (column >= itemData.count())
//		return QVariant();
//    return itemData.value(column);
//}
//! [6]

//! [7]
//ExplItem *ExplItem::parent()
//{
//    return parentItem;
//}
//! [7]

//! [8]
//int ExplItem::row() const
//{
//    if (parentItem)
//        return parentItem->childItems.indexOf(const_cast<ExplItem*>(this));
//
//    return 0;
//}
//! [8]







//void			ExplItem::setData	(int column, QVariant TheData)
//{
//	if (itemData.length() == column)
//		itemData.append(TheData);
//	else if (itemData.length() > column)
//		itemData[column] = TheData;
//	else
//		Q_ASSERT(0);
//}
